package gui;

import houseHold.HouseHoldObject;
import houseHold.Room;
import houseHold.electricObjects.ElectricObject;
import houseHold.electricObjects.ElectricObjectType;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.SystemColor;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;

import sensor.Sensor;
import sensor.SensorType;
import simulation.WriterCollection;
import constants.Constants;
import controlComponents.EnergyScale;
import controlComponents.GasScale;
import controlComponents.LightScale;
import controlComponents.PresenceViewer;
import controlComponents.ScaleWriter;
import controlComponents.TemperatureScale;
import controlComponents.WaterScale;
import controlComponents.WindowViewer;

public class SensorPanel extends JPanel {

	private static final long serialVersionUID = 1L;
	private static final int d_height = 60;
	private static final int d_width = 800;
	private Vector<Sensor> list = new Vector<Sensor>();

	/**
	 * This is the default constructor
	 */
	public SensorPanel() {
		super();
		this.setLayout(null);
		this.setBackground(new Color(250, 250, 250));

	}

	// @jve:decl-index=0:

	public void addSensors(Vector<Sensor> sensorList) {
		list.addAll(sensorList);
	}

	public void build(Room r) {
		this.setPreferredSize(new Dimension(860, list.size() * 150
				+ (list.size() - 1) * 20));
		auxComponents = new Vector<JLabel>();
		panels = new Vector<JPanel>();
		mainComponents = new Vector<JScrollPane>();
		SensorType oldtype = list.get(0).getType();
		for (int i = 0; i < list.size(); i++) {
			Sensor s = list.get(i);
			System.out.println(oldtype + " " + s.getType());
			if (oldtype != s.getType()) {
				System.out.println("building new panel");
				title = buildTitle(oldtype);
				panels.add(buildPanel(title, auxComponents, mainComponents));
				auxComponents = new Vector<JLabel>();
				mainComponents = new Vector<JScrollPane>();
			}
			oldtype = s.getType();
			switch (s.getType()) {
			case WINDOW_SENSOR:
				buildWindow(s, r);
				break;
			case GAS_SENSOR:
				buildGas(s, r);
				break;
			case WATER_SENSOR:
				buildWater(s, r);
				break;
			case ELECTRIC_SENSOR:
				buildElectric(s, r);
				break;
			case TEMPERATURE_SENSOR:
				buildTemp(s, r);
				break;
			case LIGHT_SENSOR:
				buildLight(s, r);
				break;
			case PR_SENSOR:
				buildPresence(s, r);
				break;
			}

		}
		System.out.println("building new panel");
		title = buildTitle(list.get(list.size() - 1).getType());
		panels.add(buildPanel(title, auxComponents, mainComponents));
		auxComponents = new Vector<JLabel>();
		mainComponents = new Vector<JScrollPane>();

		for (int i = 0; i < panels.size(); i++) {
			this.add(panels.get(i));
		}
		this.repaint();
	}

	private Vector<JScrollPane> mainComponents; // @jve:decl-index=0:
	private Vector<JLabel> auxComponents;
	private Vector<JPanel> panels;
	private String title;

	private JPanel buildPanel(String title, Vector<JLabel> labels,
			Vector<JScrollPane> components) {
		System.out.println(labels.size());
		JPanel panel = new JPanel();
		panel.setLayout(null);
		panel.setBounds(new Rectangle(15, getNextMasterY(), components.get(0)
				.getWidth() + 30, 130 * labels.size()));
		panel.setBackground(new Color(250, 250, 250));
		panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
				.createBevelBorder(BevelBorder.RAISED), BorderFactory
				.createTitledBorder(BorderFactory.createLineBorder(Color.gray,
						5), title, TitledBorder.DEFAULT_JUSTIFICATION,
						TitledBorder.DEFAULT_POSITION, new Font("SansSerif",
								Font.BOLD, 14), SystemColor.textHighlight)));
		for (int i = 0; i < labels.size(); i++) {
			panel.add(components.get(i));
			panel.add(labels.get(i));
		}
		masterY += 150 * labels.size() + 20;
		return panel;
	}

	private int masterY = 10;

	private int getNextMasterY() {
		return masterY;
	}

	private JPanel getNewContainer(SensorType type) {
		JPanel panel = new JPanel();

		panel.setLayout(null);
		panel.setBackground(new Color(250, 250, 250));
		JScrollPane jScrollPane = new JScrollPane();

		jScrollPane.setLocation(new Point(getNextX(), getNextY()));
		jScrollPane.setBorder(BorderFactory.createEmptyBorder());
		jScrollPane.setSize(defaultDimension(type, jScrollPane));
		jScrollPane.setPreferredSize(defaultDimension(type, jScrollPane));
		jScrollPane.setViewportView(panel);
		jScrollPane.getHorizontalScrollBar().setPreferredSize(
				new Dimension(0, 0));

		jScrollPane
				.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
		mainComponents.add(jScrollPane);
		// jScrollPane.setBorder(BorderFactory.createLineBorder(Color.red));
		return panel;
	}

	private int getNextX() {
		return 15;
	}

	private Dimension defaultDimension(SensorType type, JScrollPane p) {
		Dimension d = new Dimension();
		switch (type) {
		case WINDOW_SENSOR:
			d.setSize(190, d_height - 20);
			break;
		case PR_SENSOR:
			d.setSize(190, d_height - 20);
			break;
		default:
			d.setSize(d_width, d_height);
			p.setBorder(BorderFactory.createCompoundBorder(BorderFactory
					.createBevelBorder(BevelBorder.LOWERED), BorderFactory
					.createBevelBorder(BevelBorder.RAISED)));
			break;
		}
		return d;
	}

	private int getNextY() {
		int y = auxComponents.size() * 30 + 10 + mainComponents.size()
				* (d_height + 10) + 10;
		return y;
	}

	private String br = " <br/> ";

	private String buildMsg(Vector<String> strings) {
		String msg = new String();
		msg = "<html>";
		for (int i = 0; i < strings.size(); i++)
			msg = msg + strings.get(i) + br;
		msg = msg + "<html/>";
		return msg;
	}

	private JLabel buildConsumptionLabel(Sensor s, Room r) {

		Vector<String> data = new Vector<String>();
		data.add("SensorType = " + s.getType());
		data.add("Sensor monitoring items:");
		Set<String> st = r.getItemList().keySet();
		Iterator<String> it = st.iterator();
		while (it.hasNext()) {
			HouseHoldObject o = r.getItemList().get(it.next());
			if (o.getSensor().equals(s))
				data.add(" - " + o.getName());
		}
		String res = buildMsg(data);
		JLabel l = new JLabel(s.getSensorName());
		l.setForeground(Color.DARK_GRAY);
		l.setFont(Constants.font);
		l.setSize(180, 30);
		l.setPreferredSize(new Dimension(180, 30));
		l.setLocation(15, auxComponents.size() * 100 + 20);
		l.setToolTipText(res);
		return l;
	}

	private String buildTitle(SensorType t) {
		switch (t) {
		case WINDOW_SENSOR:
			return "Window Data";
		case GAS_SENSOR:
			return "Gas Data";
		case WATER_SENSOR:
			return "Water Data";
		case ELECTRIC_SENSOR:
			return "Electricity Data";
		case TEMPERATURE_SENSOR:
			return "Temperature Data";
		case LIGHT_SENSOR:
			return "Light Data";
		case PR_SENSOR:
			return "Presence Data";
		case RF_SENSOR:
			return "RFid Data";
		default:
			return "Sensor Data";
		}
	}

	private JLabel buildGeneralLabel(Sensor s, Room r) {

		Vector<String> data = new Vector<String>();
		data.add("SensorType = " + s.getType());
		data.add("Sensor monitoring room:");
		data.add(" - " + r.getName());
		String res = buildMsg(data);
		JLabel l = new JLabel(s.getSensorName());
		l.setForeground(Color.DARK_GRAY);
		l.setFont(Constants.font);
		l.setSize(180, 30);
		l.setPreferredSize(new Dimension(180, 30));
		l.setLocation(15, auxComponents.size() * 100 + 20);
		System.out.println(l.getLocation());
		l.setToolTipText(res);
		return l;
	}

	private void execute(ScaleWriter sw, Sensor s, Room r) {
		sw.setPanel(getNewContainer(s.getType()));
		WriterCollection.allWriters.add(sw);
		s.addScaleWriter(sw);
	}

	private void buildTemp(Sensor s, Room r) {
		ScaleWriter sw = new TemperatureScale(s.getSensorID());
		auxComponents.add(buildGeneralLabel(s, r));
		execute(sw, s, r);
	}

	private void buildLight(Sensor s, Room r) {
		ScaleWriter sw = new LightScale(s.getSensorID());
		auxComponents.add(buildGeneralLabel(s, r));
		execute(sw, s, r);
	}

	private void buildPresence(Sensor s, Room r) {
		ScaleWriter sw = new PresenceViewer(s.getSensorID());
		auxComponents.add(buildGeneralLabel(s, r));
		execute(sw, s, r);
	}

	private void buildWindow(Sensor s, Room r) {
		ScaleWriter sw = new WindowViewer(s.getSensorID());
		auxComponents.add(buildGeneralLabel(s, r));
		execute(sw, s, r);
	}

	private void buildElectric(Sensor s, Room r) {
		ScaleWriter sw = new EnergyScale(s.getSensorID());
		auxComponents.add(buildConsumptionLabel(s, r));
		execute(sw, s, r);
	}

	private void buildGas(Sensor s, Room r) {
		ScaleWriter sw = new GasScale(s.getSensorID());
		auxComponents.add(buildConsumptionLabel(s, r));
		execute(sw, s, r);
	}

	private void buildWater(Sensor s, Room r) {
		ScaleWriter sw = new WaterScale(s.getSensorID());
		auxComponents.add(buildConsumptionLabel(s, r));
		execute(sw, s, r);
	}

	public static void main(String args[]) throws InterruptedException {
		JFrame main = new JFrame();
		main.setVisible(true);
		main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		main.setSize(800, 300);
		SensorPanel sp = new SensorPanel();
		JScrollPane jsp = new JScrollPane(sp);

		main.add(jsp);
		Vector<Sensor> sensorList = new Vector<Sensor>();
		Room r = new Room();
		r.setWidth(600);
		r.setHeight(100);
		r.setLength(400);
		ElectricObject el = new ElectricObject();
		el.setConsumption(700);
		el.setType(ElectricObjectType.LIGHT, false);
		el.setActive(true);
		r.addItem(el);

		Sensor s1 = new Sensor();
		r.addSensor(s1);
		s1.setType(SensorType.ELECTRIC_SENSOR);
		el.setSensor(s1);

		Sensor s2 = new Sensor();
		r.addSensor(s2);
		s2.setType(SensorType.ELECTRIC_SENSOR);

		sensorList.add(s1);
		sensorList.add(s2);

		sp.addSensors(sensorList);
		sp.build(r);
		WriterCollection.startAll();
		// WriterCollection.allWriters.get(2).runWorker();
		// WriterCollection.allWriters.get(3).runWorker();

		r.setWindowStatus(true);
		// Thread.sleep(100);

		for (int i = 0; i < 900; i++) {
			s1.getSensorData(r, i);
			s2.getSensorData(r, i);

		}

		WriterCollection.allWriters.get(0).finished();
		WriterCollection.allWriters.get(1).finished();

	}

}
